package com.jmb.api.web.service.impl;

import com.alibaba.fastjson2.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.jmb.api.common.exception.WebApiException;
import com.jmb.api.common.login.LoginUserHolder;
import com.jmb.api.common.result.ResultCodeEnum;
import com.jmb.api.common.utils.JwtUtil;
import com.jmb.api.common.utils.LoginConstants;
import com.jmb.api.common.utils.RedisUtil;
import com.jmb.api.entity.LogInfoVo;
import com.jmb.api.entity.Role;
import com.jmb.api.entity.User;
import com.jmb.api.vo.Login.LoginVo;
import com.jmb.api.vo.user.UserInfoVO;
import com.jmb.api.vo.user.UserQueryVO;
import com.jmb.api.vo.user.UserVO;
import com.jmb.api.web.service.RoleService;
import com.jmb.api.web.service.UserService;
import com.jmb.api.web.mapper.UserMapper;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;

import static com.jmb.api.common.utils.LoginConstants.loginInfo;
import static com.jmb.api.common.utils.LoginConstants.tokenExpiration;

/**
* @author 金梦博
* @description 针对表【t_user】的数据库操作Service实现
* @createDate 2025-09-25 17:21:23
*/
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Autowired
    private UserMapper userMapper;
    @Autowired
    private RoleService roleService;
    @Autowired
    private RedisUtil redisUtil;

    @Override
    public void registerUser(User user)   {
        // 对密码进行加密
        user.setPassword(DigestUtils.md5Hex(user.getPassword()));
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, user.getUsername());
        if (this.count(queryWrapper) > 0){
            throw new WebApiException(ResultCodeEnum.web_ACCOUNT_EXIST_ERROR);
        }
        userMapper.insert(user);
    }

    // 新增用户
    @Override
    public void saveOrUpdateUser(User user) {
        // 我们先判断新增还是修改
        boolean isUpdate = user.getId() != null;

        String password = user.getPassword();

        // 校验角色名称是否已存在
        LambdaQueryWrapper<User> userWrapper = new LambdaQueryWrapper<>();
        userWrapper.eq(User::getUsername, user.getUsername());

        // 如果是修改操作，需要排除当前角色本身
        if (isUpdate){
            userWrapper.ne(User::getId, user.getId());
        }

        // 查询是否存在相同角色名称
        User existingUser = userMapper.selectOne(userWrapper);
        if (existingUser != null){
            // 角色已存在，抛出异常
            throw new WebApiException(ResultCodeEnum.web_ACCOUNT_EXIST_ERROR);
        }
        if (password != null && !password.isEmpty()){
            user.setPassword(DigestUtils.md5Hex(password));
        }else if (user.getId()!=null){
            User userPassword = userMapper.selectById(user.getId());
            user.setPassword(userPassword.getPassword());
        }
        super.saveOrUpdate(user);

    }

    /**
     * 重置密码
     * @param userId 用户id
     */
    @Override
    public void resetPassword(Long userId) {
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getId, userId);
        User user = userMapper.selectOne(queryWrapper);
        user.setPassword(DigestUtils.md5Hex("123456"));
        userMapper.updateById(user);
    }

    @Override
    public IPage<UserInfoVO> pageUserInfo(IPage<UserInfoVO> page, UserQueryVO queryVO) {
        return userMapper.pageUserInfo(page, queryVO);
    }

    @Override
    public String login(LoginVo loginVo) {
        // 登录逻辑
        // 校验用户名是否存在
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUsername, loginVo.getUsername());
        User user = userMapper.selectOne(queryWrapper);
        if (user ==null){
            throw new WebApiException(ResultCodeEnum.web_ACCOUNT_NOT_EXIST_ERROR);
        }
        // 校验用户是否被禁
        if (user.getIsEnable() == 0){
            throw new WebApiException(ResultCodeEnum.web_ACCOUNT_DISABLED_ERROR);
        }
        // 校验用户密码
        String password = DigestUtils.md5Hex(loginVo.getPassword());
        if (!user.getPassword().equals(password)){
            log.info("用户密码错误,错误密码是 {} ", password);
            throw new WebApiException(ResultCodeEnum.web_ACCOUNT_ERROR);
        }
        return JwtUtil.createToken(user.getId(),user.getUsername());
    }

    @Override
    public LogInfoVo getLoginUserInfo() {
        Long userId = LoginUserHolder.getLoginUser().getUserId();
        String username = LoginUserHolder.getLoginUser().getUsername();
        LambdaQueryWrapper<User> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(User::getId, userId);
        User user = userMapper.selectOne(userQuery);
        if (user ==null){
            throw new WebApiException(ResultCodeEnum.web_ACCOUNT_NOT_EXIST_ERROR);
        }
        HashMap<String, Object> userMap = new HashMap<>();
        userMap.put("Userid", userId);
        userMap.put("username", username);
        userMap.put("realName", user.getRealName());
        userMap.put("isEnable", user.getIsEnable());
        Long roleId = user.getRoleId();
        JSONArray permissionCodeArrayByRoleId = roleService.findPermissionCodeArrayByRoleId(roleId);
        userMap.put("permission", permissionCodeArrayByRoleId);
        // 写入权限，写入到redis
        log.info("写入权限 {}", userMap);
        redisUtil.set(loginInfo+userId, userMap,tokenExpiration);
        LogInfoVo logInfoVo = new LogInfoVo();
        logInfoVo.setUserId(userId);
        logInfoVo.setPermissions(permissionCodeArrayByRoleId);
        logInfoVo.setUsername(username);
        logInfoVo.setRoleName(user.getRealName());
        logInfoVo.setIsEnable(user.getIsEnable());
        return logInfoVo;


    }

    // 写入权限使用
    @Override
    public LogInfoVo getLoginUserInfoToken(String token) {
        Claims claims = JwtUtil.parseToken(token);
        Long userId = claims.get("userId", Long.class);
        String username = claims.get("username", String.class);
        LambdaQueryWrapper<User> userQuery = new LambdaQueryWrapper<>();
        userQuery.eq(User::getId, userId);
        User user = userMapper.selectOne(userQuery);
        if (user ==null){
            throw new WebApiException(ResultCodeEnum.web_ACCOUNT_NOT_EXIST_ERROR);
        }
        HashMap<String, Object> userMap = new HashMap<>();
        userMap.put("Userid", userId);
        userMap.put("username", username);
        userMap.put("realName", user.getRealName());
        userMap.put("isEnable", user.getIsEnable());
        userMap.put("token", token);
        Long roleId = user.getRoleId();
        JSONArray permissionCodeArrayByRoleId = roleService.findPermissionCodeArrayByRoleId(roleId);
        userMap.put("permission", permissionCodeArrayByRoleId);
        // 写入权限，写入到redis
        log.info("写入权限 {}", userMap);
        redisUtil.set(loginInfo+userId, userMap,tokenExpiration);
        LogInfoVo logInfoVo = new LogInfoVo();
        logInfoVo.setUserId(userId);
        logInfoVo.setPermissions(permissionCodeArrayByRoleId);
        logInfoVo.setUsername(username);
        logInfoVo.setRoleName(user.getRealName());
        logInfoVo.setIsEnable(user.getIsEnable());
        logInfoVo.setToken(token);
        return logInfoVo;
    }


}




